import 'package:async/async.dart';
import 'package:bai_le_men_im/cmomon/utils.dart';
import 'package:bai_le_men_im/conversation/conversationGroup_detail_page.dart';
import 'package:flutter/material.dart';
import 'package:overlay_support/overlay_support.dart';
import '../conversation/inputPanel/entry.dart';

import '../constants.dart' show AppColors, AppStyles, Constants;
import 'package:flutter_wildfire/flutter_wildfire.dart';
import 'package:intl/intl.dart';
import '../models/index.dart';
import 'package:flutter_sound/flutter_sound.dart';
import './conversationItemContent.dart';

List<User> users = new List<User>();
updateUser(User _user) {
  int index = users.indexWhere((User user) => user.uid == _user.uid);
  if (index > -1) {
    users[index] = _user;
  } else {
    users.add(_user);
  }
}

getUserById(String userId, {bool force = false}) async {
  // 因为异步的原因这里不能保证数组中没有重复
  int index = users.indexWhere((User user) => user.uid == userId);
  User user;
  if (force || index == -1) {
    var result = await FlutterWildfire.getUserInfo(userId, true);
    user = User.fromJson(result);
  }
  if (index > -1) {
    if (user != null) users[index] = user;
    return users[index];
  } else {
    if (user != null) users.add(user);
    return user;
  }
}

User getUserByIdSync(String userId) {
  int index = users.indexWhere((User user) => user.uid == userId);
  if (index > -1) {
    return users[index];
  } else {
    getUserById(userId);
  }
  User user;
  return user;
}

const int CountdownNum = 10;
const int pageSize = 20;
final DateFormat formatter = new DateFormat('MM-DD HH:mm');

FlutterSound flutterSound = new FlutterSound();

class GroupMessagesPage extends StatefulWidget {
  final int messageId;
  Group groupInfo;
  final Function clearMessagesHandler;
  GroupMessagesPage(
      {@required this.groupInfo, this.messageId, this.clearMessagesHandler});
  @override
  _MessagesPageState createState() => _MessagesPageState();
}

class _MessagesPageState extends State<GroupMessagesPage> {
  ScrollController _scrollController = new ScrollController();
  String targetId;
  List msgList;
  bool isRefreshing = false;
  bool isNoMoreData = false;
  bool isFetching = false;
  String conversationType;
  bool isDismissed = false;

  refreshTarget() async {
    var target = widget.groupInfo;
    if (target is Group) {
      var result = await FlutterWildfire.getGroupInfo(target.target);
      Group group = Group.fromJson(result);
      widget.groupInfo = group;
    }
  }

  getMessages(int fromIndex, int count) async {
    if (isFetching) return;
    if (isNoMoreData) return;
    isFetching = true;
    msgList = msgList == null ? [] : (msgList.length > 0 ? msgList : []);
    var result = await FlutterWildfire.getMessages(
        conversationType, targetId, 0, fromIndex, true, count, null);
    if (result != null && result.length > 0) {
      msgList.addAll(List.generate(result.length, (index) {
        var _obj = result[result.length - 1 - index];
        return _obj;
      }));
      isFetching = false;
      isNoMoreData = result.length < pageSize;
      this.setState(() {});
      // _scrollController.
      return;
    }
    print('从本地没找到，从远程找');
    // result = await FlutterWildfire.getRemoteMessages(
    //     conversationType, targetId, 0, fromIndex, count);
    // if (result != null && result.length > 0) {
    //   msgList.addAll(List.generate(result.length, (index) {
    //     var _obj = result[result.length - 1 - index];
    //     return _obj;
    //   }));
    //   isFetching = false;
    //   isNoMoreData = result.length < pageSize;
    //   this.setState(() {});
    //   return;
    // }

    isFetching = false;
    isNoMoreData = true;
    print('从远程没有找到');
    this.setState(() {});
    return;
  }

  initPage() {
    getMessages(0, pageSize);
  }

  sendMessageOnProgress(dynamic event) async {
    // print('sendMessageOnProgress');
    // print(event);
    dynamic message = event['message'];
    message['total'] = event['total'];
    message['uploaded'] = event['uploaded'];
    int index =
        msgList.indexWhere((item) => item['messageId'] == message['messageId']);
    if (index > -1) {
      this.setState(() {
        msgList[index] = message;
      });
    } else {
      this.setState(() {
        msgList.insert(0, message);
      });
    }
  }

  sendMessageOnMediaUpload(dynamic event) async {
    dynamic message = event['message'];
    message['remoteUrl'] = event['remoteUrl'];
    int index =
        msgList.indexWhere((item) => item['messageId'] == message['messageId']);
    if (index > -1) {
      this.setState(() {
        msgList[index] = message;
      });
    } else {
      this.setState(() {
        msgList.insert(0, message);
      });
    }
  }

  sendMessageOnPrepareHandler(dynamic message) async {
    print('sendMessageOnPrepareHandler');
    print(message);
    int index =
        msgList.indexWhere((item) => item['messageId'] == message['messageId']);
    if (index > -1) {
      this.setState(() {
        msgList[index] = message;
      });
    } else {
      this.setState(() {
        msgList.insert(0, message);
      });
    }
  }

  receiveMessagesHandler(dynamic messages) async {
    var message = messages[0];
    receiveMessageHandler(message, false);
  }

  receiveMessageHandler(dynamic message, bool clearUnRead) async {
    String otherSideUserId = message['conversation']['target'];
    // print(ModalRoute.of(context).isActive);
    // print(ModalRoute.of(context).isCurrent);
    // print(ModalRoute.of(context).isFirst);
    // List list = ModalRoute.of(context).overlayEntries;
    // print(list);
    if (otherSideUserId != targetId) {
      if (ModalRoute.of(context).isCurrent) {
        print('收到别人的短信后的弹窗');
      }
      return;
    }
    String type = message['type'];
    if (type != null && type == 'TypingMessageContent') {
      // TODO: 输入状态
      // reGetCountdown();
      return;
    } else if (type != null &&
        [
          'TextMessageContent',
          'ImageMessageContent',
          'SoundMessageContent',
          'ChangeGroupNameNotificationContent',
          'AddGroupMemberNotificationContent',
          'QuitGroupNotificationContent',
          'DismissGroupNotificationContent'
        ].contains(type)) {
      switch (type) {
        case 'DismissGroupNotificationContent':
          widget.groupInfo.memberCount = 0;
          isDismissed = true;
          break;
        case 'QuitGroupNotificationContent':
          int memberCount = widget.groupInfo.memberCount - 1;
          if (memberCount <= 1) memberCount = 1;
          widget.groupInfo.memberCount = memberCount;
          break;
        case 'AddGroupMemberNotificationContent':
          int memberCount = widget.groupInfo.memberCount + 1;
          if (memberCount <= 1) memberCount = 1;
          widget.groupInfo.memberCount = memberCount;
          break;
        case 'ChangeGroupNameNotificationContent':
          widget.groupInfo.name = message['content']['name'];
          break;
        case 'TextMessageContent':
        case 'ImageMessageContent':
        case 'SoundMessageContent':
          break;
        default:
      }
      recevieSigleMessage(message, type);
    } else {
      print(message);
      print('有可能是别的类型的消息3');
      print('会话详情里面 receiveMessage handler');
    }
  }

  recevieSigleMessage(message, type) {
    msgList.insert(0, {
      "type": type,
      "content": message['content'],
      "conversation": message['conversation'],
      "direction": "Receive",
      "messageId": message['messageId'],
      "messageUid": message['messageUid'],
      "sender": message['sender'],
      "serverTime": message['serverTime'],
      "status": message['status']
    });

    this.setState(() {});
  }

  @override
  void initState() {
    super.initState();
    targetId = widget.groupInfo.target;
    conversationType = 'Group';
    print('Group message Page initState');
    initPage();
    _scrollController.addListener(_scrollHanlder);
    FlutterWildfire.on("receiveMessage", receiveMessagesHandler);
    // FlutterWildfire.on("sendMessageOnProgress", sendMessageOnProgress);
    FlutterWildfire.on("sendMessageOnMediaUpload", sendMessageOnMediaUpload);
    FlutterWildfire.on("sendMessageOnPrepare", sendMessageOnPrepareHandler);
  }

  @override
  void dispose() {
    FlutterWildfire.off("sendMessageOnPrepare", sendMessageOnPrepareHandler);
    // FlutterWildfire.off("sendMessageOnProgress", sendMessageOnProgress);
    FlutterWildfire.off("sendMessageOnMediaUpload", sendMessageOnMediaUpload);
    FlutterWildfire.off("receiveMessage", receiveMessagesHandler);
    _scrollController.removeListener(_scrollHanlder);
    _scrollController.dispose();
    super.dispose();
  }

  _scrollHanlder() {
    if (_scrollController.position.pixels ==
            _scrollController.position.maxScrollExtent &&
        !this.isRefreshing &&
        !this.isNoMoreData) {
      // print('滑动到最底部了');
      getMessages(msgList.last['messageId'], pageSize);
    }
  }

  clearMessagesHandler() async {
    await FlutterWildfire.clearMessages(conversationType, targetId, 0);
    this.setState(() {
      isNoMoreData = true;
      msgList.clear();
    });
    if (widget.clearMessagesHandler != null) {
      widget.clearMessagesHandler();
    }
  }

  _onSendMsgHandler(payload, String type) async {
    var result;
    if (type == 'text') {
      try {
        result = await FlutterWildfire.sendTextMessage(
            conversationType, targetId, 0, null, payload);
      } catch (e) {} finally {}
    } else if (type == 'image') {
      try {
        result = await FlutterWildfire.sendImgMessage(
            conversationType, targetId, 0, null, payload);
      } catch (e) {
        print('发送图片文件错误');
        print(e);
      }
    } else if (type == 'audio') {
      try {
        result = await FlutterWildfire.sendAudioMessage(conversationType,
            targetId, 0, payload['path'], payload["duration"]);
      } catch (e) {
        print('发送语音文件错误');
        print(e);
      }
    } else if (type == 'RedEnvelope') {
      toast('暂未开通群红包的功能');
    } else {
      print('未知的发送类型');
    }
    if (result != null) {
      int index = msgList
          .indexWhere((item) => item['messageId'] == result['messageId']);
      if (index > -1) {
        this.setState(() {
          msgList[index] = result;
        });
      } else {
        this.setState(() {
          msgList.insert(0, result);
        });
      }
    }
  }

  String getUserNameByIdSync(String userId) {
    User user = getUserByIdSync(userId);
    if (user != null) {
      String name = (user.friendAlias != null && user.friendAlias.isNotEmpty)
          ? user.friendAlias
          : user.displayName;
      return name;
    }
    return userId;
  }

  @override
  Widget build(BuildContext context) {
    String displayName =
        widget.groupInfo.name + '(${widget.groupInfo.memberCount})';
    return Scaffold(
        appBar: AppBar(
          title: Text(displayName, style: AppStyles.TitleStyle),
          leading: IconButton(
              onPressed: () {
                if (isDismissed) {
                  Navigator.of(context).pop();
                  return;
                }
                Navigator.pop(
                    context, msgList.length > 0 ? msgList.first : null);
              },
              icon: Icon(
                  IconData(
                    0xe64c,
                    fontFamily: Constants.IconFontFamily,
                  ),
                  size: Constants.ActionIconSize + 4.0,
                  color: const Color(AppColors.ActionIconColor))),
          elevation: 0.0,
          brightness: Brightness.light,
          backgroundColor: const Color(AppColors.PrimaryColor),
          actions: [
            IconButton(
                onPressed: () async {
                  if (isDismissed) {
                    toast('操作失败');
                    return;
                  }
                  await Navigator.of(context)
                      .push(new MaterialPageRoute(builder: (context) {
                    return ConversationGroupDetailPage(
                        clearMessagesHandler: clearMessagesHandler,
                        groupInfo: widget.groupInfo);
                  }));
                },
                icon: Icon(
                    IconData(
                      0xe609,
                      fontFamily: Constants.IconFontFamily,
                    ),
                    size: Constants.ActionIconSize + 4.0,
                    color: const Color(AppColors.ActionIconColor))),
            SizedBox(width: 16.0)
          ],
        ),
        body: Column(
          children: <Widget>[
            Expanded(
              child: Container(
                width: double.infinity,
                color: const Color(AppColors.BackgroundColor),
                child: msgList != null
                    ? ListView.builder(
                        reverse: true,
                        controller: _scrollController,
                        itemBuilder: (BuildContext context, int index) {
                          if (index == msgList.length) {
                            if (isNoMoreData) {
                              return Container(
                                  // child: Text('没有更多了'),
                                  );
                            }
                            return Center(
                              child: SizedBox(
                                width: 30.0,
                                height: 30.0,
                                child: CircularProgressIndicator(
                                    // strokeWidth: 2.0,
                                    ),
                              ),
                            );
                          }
                          var item = msgList[index];
                          bool isTip = false;
                          String tipStr;
                          if (item['content']['content'] != null ||
                              item['content']['mediaType'] != null) {
                            return Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: ConversationItem(
                                key: Key(item['messageUid'].toString()),
                                ownerId: item['sender'],
                                data: item,
                              ),
                            );
                          } else if (item['type'] != null && [
                            'QuitGroupNotificationContent',
                            'DismissGroupNotificationContent'
                            ].contains(item['type'])) {
                            String type = item['type'];
                            isTip = true;
                            switch (type) {
                              case 'DismissGroupNotificationContent':
                                tipStr = getUserNameByIdSync(
                                      item['content']['operator']);
                                tipStr += '解散了群组';
                                break;
                              
                              case 'QuitGroupNotificationContent':
                                tipStr = getUserNameByIdSync(
                                      item['content']['operator']);
                                tipStr += '退出了群组';
                                break;
                              case 'AddGroupMemberNotificationContent':
                                
                                break;
                              case 'ChangeGroupNameNotificationContent':
                                
                                break;
                              case 'TextMessageContent':
                              case 'ImageMessageContent':
                              case 'SoundMessageContent':
                                break;
                              default:
                            }
                          } else if (item['content']['tip'] != null ||
                              (item['content']['groupName'] != null &&
                                  item['content']['fromSelf'] != null)) {
                            isTip = true;
                            if (item['content']['tip'] != null) {
                              tipStr = item['content']['tip'];
                            } else {
                              if (item['content']['creator'] != null ||
                                  item['content']['groupName'] != null) {
                                // 创建群组消息
                                if (item['content']['fromSelf']) {
                                  tipStr = '您';
                                } else {
                                  tipStr = getUserNameByIdSync(
                                      item['content']['creator']);
                                }
                                tipStr +=
                                    '创建了群组 ${item['content']['groupName']}';
                              } else {
                                print('可能不是创建群组消息');
                                tipStr = '';
                              }
                            }
                          } else if (item['content']['operateUser'] != null) {
                            isTip = true;
                            if (item['content']['name'] != null) {
                              tipStr =
                                  '${getUserNameByIdSync(item['content']['operateUser'])}修改群组名为${item['content']['name']}';
                            } else {
                              // TODO: 对群组的其它操作
                              print('对群组的其它操作');
                              tipStr = '';
                            }
                          } else if (item['content']['invitor'] != null) {
                            isTip = true;
                            List<String> inviteesNames = new List<String>();
                            for (var item in item['content']['invitees']) {
                              inviteesNames.add(getUserNameByIdSync(item));
                            }
                            tipStr =
                                '${getUserNameByIdSync(item['content']['invitor'])}邀请${inviteesNames.join(',')}加入了群聊';
                          } else {
                            print('未知类型2');
                            // TODO： 未知类型
                            print(item);
                            return Container();
                          }
                          if (isTip) {
                            return Center(
                              child: Container(
                                margin: EdgeInsets.all(8.0),
                                padding: EdgeInsets.symmetric(
                                    horizontal: 6.0, vertical: 8.0),
                                decoration: BoxDecoration(
                                    color: Colors.grey[400],
                                    borderRadius: BorderRadius.circular(3.0)),
                                child: Text(
                                  tipStr,
                                  style: TextStyle(color: Colors.white),
                                ),
                              ),
                            );
                          }
                        },
                        itemCount: msgList.length + 1)
                    : Column(
                        children: <Widget>[
                          SizedBox(
                            height: 20.0,
                          ),
                          CircularProgressIndicator()
                        ],
                      ),
              ),
            ),
            isDismissed
                ? Container()
                : InputPanel(onSendMsgHandler: _onSendMsgHandler)
          ],
        ));
  }
}

class ConversationItem extends StatefulWidget {
  final data;
  final String ownerId;
  ConversationItem({@required this.data, this.ownerId, Key key})
      : super(key: key);

  @override
  _ConversationItemState createState() => _ConversationItemState();
}

class _ConversationItemState extends State<ConversationItem> {
  final AsyncMemoizer _memoizer = AsyncMemoizer();
  getUserInfoById(String userId) {
    return _memoizer.runOnce(() async {
      return await getUserById(userId);
    });
  }

  @override
  Widget build(BuildContext context) {
    Widget avatar = ClipRRect(
      borderRadius: BorderRadius.circular(Constants.AvatarRadius),
      child: FutureBuilder(
        future: getUserInfoById(widget.ownerId),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          // return Container();
          if (!snapshot.hasData) {
            return myAvatar('', size: Constants.ConversationAvatarSize);
          }
          // return SizedBox(width: 50.0, height: 50.0, child: Text(snapshot.data.dispayName),);
          return myAvatar(snapshot.data.portrait,
              size: Constants.ConversationAvatarSize);
        },
      ),
    );

    final data = widget.data;
    if (data['direction'] == 'Receive') {
      return Container(
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            avatar,
            ConversationItemContent(
                payload: data,
                flutterSound: flutterSound,
                content: data['content'],
                messageId: data['messageId']),
            SizedBox(
              width: 50.0,
            )
          ],
        ),
      );
    } else if (data['direction'] == 'Send') {
      return Container(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.end,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            SizedBox(
              width: 50.0,
            ),
            SendStatus(data['status']),
            ConversationItemContent(
                payload: data,
                messageId: data['messageId'],
                flutterSound: flutterSound,
                reverse: true,
                color: Colors.green,
                content: data['content'],
                uploadProgress: data['remoteUrl'] != null ? 0.0 : 1.0),
            avatar,
          ],
        ),
      );
    } else {
      print(data);
      return Text('未知的方向， 或者未知数据类型');
    }
  }
}
